///--------------------------------------------------
/**
 *
 *      Hand Gesture Recognition System
 *
 */
//--------------------------------------------------
/**
 * //LISTENEBLE CLASS//
 * Captura de los frames de la camara para su tratamiento.
 *
 * @author  Edwin Cobos & Cesar Murcia & Wilson Sarmiento
 * @version HGR_v1.5
 *
 * Revisado: 22/02/12
 */
//--------------------------------------------------
//PACKAGE//
package HGR;
//IMPORT//
import OpenCV.cv;
import OpenCV.cv.IplImage;
import com.sun.jna.Pointer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
//--------------------------------------------------
/**
 *Captura de los frames de la camara para su tratamiento. Implementada de @Listenable
 */
public class CamCapture extends Thread implements Listenable
{
    //--------------------------------------------------
    private Pointer         CamDevice;
    private int             width;
    private int             height;
    private int             length;
    private int             framecount;
    private Pointer         image_gray;
    private Frame           ActualFrame;
    private int             updateBackGround;
    private float[]         bufProc;
    private float[]         BackGround;
    private float[]         buffer;
    private int             k;
    private float           AvgBackGround;
    private float           VarBackGround;
    private CamDisplay      show;
    private PreProcessing   PreProc;        
    //--------------------------------------------------
    /**
     * Constructor predeterminado
     */
    public CamCapture()
    {
        CamDevice = Core.StartCamera();
        if(CamDevice != null)
        {            
            Pointer f = cv.createImage(HGR_gui.inWidth, HGR_gui.inHeight, 8, 3);
            cv.Resize(cv.queryFrame(CamDevice), f, 0);
            IplImage image_ptr = new IplImage(f);

            height = image_ptr.height;
            width  = image_ptr.width;

            length = height*width;
            framecount = 0;
            image_gray = cv.createImage(width, height, 8, 1);
            ActualFrame = new Frame();
            buffer = new float[length];
            bufProc = new float[length];
            updateBackGround = 0;
        }
    }
    //--------------------------------------------------
    /**
     * Comprueba la disponibilidad de la camara
     * @return Disponibilidad de la camara.
     */
    public boolean  IsCamera()
    {
        if(CamDevice == null)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    //--------------------------------------------------
    /**
     * Corre el proceso de captura
     */
    @Override
    public void Listen()
    {        
        if(CamDevice == null)
        {
            try
            {
                finalize();
            } 
            catch (Throwable ex)
            {
                Logger.getLogger(CamCapture.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        ActualFrame.setFrame(Core.CaptureFrame(CamDevice, image_gray, length),framecount, width, height);
        //--------------------
        //Establecer BG
        MakeBG(10);
        //--------------------     
        //CamDisplay
        if(updateBackGround == 10)
        {
            if(HGR_gui.VisCheck.isSelected()){
                show = new CamDisplay(ActualFrame, HGR_gui.CamaraFrame);
                show.start();
            }
            /*try {
                show.join();
            } catch (InterruptedException ex) {
                Logger.getLogger(CamCapture.class.getName()).log(Level.SEVERE, null, ex);
            }*/
            //   System.out.println("FRAME " + ActualFrame.getIndice());
            //--------------------
            //Iniciar PreProcesamiento
            System.out.println("COUNT = "+HGR_gui.count);
            HGR_gui.count++;
            PreProc = new PreProcessing(ActualFrame, BackGround, AvgBackGround, VarBackGround);
            PreProc.start();

            if(HGR_gui.count == 10)
            {
                while(HGR_gui.count > 9)
                {
                    System.out.print("");                
                }
            }

        }

        //--------------------
        //Incremento de Frames
        framecount++;
    }
    //--------------------------------------------------
    /**
     * Calcula la imagen de Fondo para el Background Subtraction promediando un
     * número de frames determinado
     * @param numframes número de frames a promediar
     */
    public void MakeBG(int numframes)
    {
        if(updateBackGround<numframes)
        {
            if(updateBackGround == 0)
            {
                bufProc = ActualFrame.getBuffer();
                bufProc = Core.LowPassFilter(bufProc, Core.lp_kernel, width, height);
                bufProc = Core.MedianFilter(bufProc, 3, width, height);
                BackGround = bufProc;              
            }
            else
            {
                bufProc = ActualFrame.getBuffer();
                bufProc = Core.LowPassFilter(bufProc, Core.lp_kernel,width, height);
                bufProc = Core.MedianFilter(bufProc, 3, width, height);
                
                for(k=0; k<length; k++)
                {                    
                    buffer[k] = (bufProc[k] + BackGround[k])/2.0f;
                }
                BackGround = buffer;
            }
            if(updateBackGround == 9)
            {
                float conBg;
                for(k=0; k<length; k++)
                {
                    conBg = BackGround[k] * HGR_gui.GetContrastBg();
                    if(conBg < 255.0 && conBg > 0.0)
                    {
                        buffer[k] = conBg;
                    }
                    if(conBg > 255.0)
                    {
                        buffer[k] = 255;
                    }
                    if(conBg < 0.0)
                    {
                        buffer[k] = 0;
                    }
                    buffer[k] = BackGround[k] * HGR_gui.GetContrastBg();
                }
                 BackGround = buffer;
               AvgBackGround = Core.avgImage(BackGround);
               VarBackGround = Core.varImage(BackGround, AvgBackGround);
               HGR_gui.out_tex.setText("Activo");
            }
            updateBackGround++;
        }       
    }
    //--------------------------------------------------    
    public void updateBackGround()
    {
        updateBackGround = 0;
    }
    //--------------------------------------------------
}
//--------------------------------------------------
//FIN
//--------------------------------------------------